package com.atguigu.daijia.common.feign;

import com.atguigu.daijia.common.result.Result;
import com.atguigu.daijia.common.result.ResultCodeEnum;
import feign.Response;
import feign.codec.DecodeException;
import feign.codec.Decoder;
import org.springframework.cloud.openfeign.support.SpringDecoder;

import java.io.IOException;
import java.lang.reflect.Type;
import java.util.Objects;

/**
 * @create: 2024/9/21
 * @author: gyhe10
 * @description: 自定义 OpenFeign 远程调用结果解析解码器
 **/

public class FeignCustomDataDecoder implements Decoder {
    private final SpringDecoder decoder;

    public FeignCustomDataDecoder(SpringDecoder decoder) {
        this.decoder = decoder;
    }

    @Override
    public Object decode(Response response, Type type) throws IOException {
        Object object = this.decoder.decode(response, type);
        // 解码结果是否为空，若为空则抛出异常
        if (object == null) {
            throw new DecodeException(ResultCodeEnum.FEIGN_FAIL.getCode(), ResultCodeEnum.FEIGN_FAIL.getMessage(), response.request());
        }
        if (object instanceof Result<?>) {
            // 若解码结果为 Result 类型，进一步检查其状态码是否为成功，否则抛出异常
            // 如果 Result 中的数据为空，同样抛出异常；否则返回 Result 对象
            Result<?> result = (Result<?>) object;
            if (!Objects.equals(result.getCode(), ResultCodeEnum.SUCCESS.getCode())) {
                throw new DecodeException(result.getCode(), result.getMessage(), response.request());
            }
            // 如果远程调用的结果为空，抛出异常
            if (result.getData() == null) {
                throw new DecodeException(ResultCodeEnum.FEIGN_FAIL.getCode(), ResultCodeEnum.FEIGN_FAIL.getMessage(), response.request());
            }
            return result;
        }
        // 对于非 Result 类型的解码结果，直接返回
        return object;
    }
}
